package com.interceptor;

import com.alibaba.fastjson.JSON;
import com.domain.Employee;
import com.service.PermissionService;
import com.util.JsonResult;
import com.util.RequiredPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author shkstart
 * @create 2022/3/15-9:35
 */
public class PermissionInterceptor implements HandlerInterceptor {
    @Autowired
    private PermissionService service;
    //Object handler：被拦截的控制器对象
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1、获取当前登录用户（因为已经有登录拦截器，这里一定能获取到用户，就不需要判空了）
        Employee employee = (Employee) request.getSession().getAttribute("EMP_IN_SESSION");
        // 2、判断是否是超级管理员
        if(employee.isAdmin()){  //因为admin属性是基本数据类型boolean，如果是包装类Boolean，就报错
            //是 -> 放行
            return true;
        }
            //不是 -> 下一步
        // 3、获取当前要执行的控制器的处理方法（被拦截的方法）
        //if(handler instanceof HandlerMethod) 如果中央调度器的路径是 / ，包含了静态资源，就要判断一下
        if (!(handler instanceof HandlerMethod)){
            //说明访问的是静态资源
            return true;
        }
        HandlerMethod method = (HandlerMethod)handler;
        // 4、判断是否贴了权限注解 @RequiredPermission
        RequiredPermission annotation = method.getMethodAnnotation(RequiredPermission.class);
        if(annotation==null){
            //不是 -> 放行
            return true;
        }
            //是 -> 下一步
        // 5、获取方法的权限表达式
        //方式一：通过权限注解获取权限表达式
        String expression = annotation.expression();
        /*
          方式二：通过反射来获取权限表达式
            String simpleName = handlerMethod.getBean().getClass().getSimpleName().replace("Controller","");
            String expression = StringUtils.uncapitalize(simpleName)+":"+handlerMethod.getMethod().getName();
         */
        // 6、获取当前登录用户拥有的权限表达式集合 List<String>
        List<String> permissions  = (List<String>) request.getSession().getAttribute("USER_EXPRESSIONS_IN_SESSION");
        //List<String> permissions = service.selectByEmpId(employee.getId());
        // 7、判断户拥有的权限表达式集合是否包含该方法的权限表达式
        if(permissions.contains(expression)){ //permissions、expression 类型要保持一致
            return true;  //放行
        }
        // 8、判断是否是Ajax请求的地方
        if (!(method.hasMethodAnnotation(ResponseBody.class))){ //判断是否有ResponseBody注解
            //跳转到没权限的提示页面
            request.getRequestDispatcher("/WEB-INF/views/common/nopermission.jsp").forward(request,response);
        }else {
            //响应JSON数据
            JsonResult jsonResult = new JsonResult(false, "您没有权限操作");
            //编码
            response.setContentType("application/json;charset=utf-8");
            //使用工具类将 对象 转为JSON数据
            response.getWriter().print(JSON.toJSONString(jsonResult));
        }
        return false;  //不放行
    }
}
